<?php

namespace catchAdmin\develop\controller;

use catcher\base\CatchRequest as Request;
use catcher\CatchAdmin;
use catcher\CatchResponse;
use catcher\base\CatchController;
use catchAdmin\develop\model\Codelabs as CodelabsModel;
use catcher\facade\FileSystem;
use catcher\Utils;
use think\facade\Console;
use think\facade\Log;
use think\Response;
use catchAdmin\develop\model\CodelabsTemplates;
use catchAdmin\develop\model\CodelabsAlgorithm;
use uctoo\uctoocloud\client\Http;

class Codelabs extends CatchController
{
    
    protected $codelabsModel;
    
    /**
     *
     * @time 2021/11/03 12:32
     * @param CodelabsModel $codelabsModel
     * @return mixed
     */
    public function __construct(CodelabsModel $codelabsModel)
    {
        $this->codelabsModel = $codelabsModel;
    }
    
    /**
     *
     * @time 2021/11/03 12:32
     * @return Response
     */
    public function index() : Response
    {
        return CatchResponse::paginate($this->codelabsModel->getList());
    }
    
    /**
     *
     * @time 2021/11/03 12:32
     * @param Request $request
     * @return Response
     */
    public function save(Request $request) : Response
    {
        return CatchResponse::success($this->codelabsModel->storeBy($request->post()));
    }
    
    /**
     *
     * @time 2021/11/03 12:32
     * @param $id
     * @return Response
     */
    public function read($id) : Response
    {
        return CatchResponse::success($this->codelabsModel->findBy($id));
    }
    
    /**
     *
     * @time 2021/11/03 12:32
     * @param $id
     * @param Request $request
     * @return Response
     */
    public function update($id, Request $request) : Response
    {
        return CatchResponse::success($this->codelabsModel->updateBy($id, $request->post()));
    }
    
    /**
     *
     * @time 2021/11/03 12:32
     * @param $id
     * @return Response
     */
    public function delete($id) : Response
    {
        return CatchResponse::success($this->codelabsModel->deleteBy($id));
    }

    /**
     *
     * @time 2021/11/02 09:12
     * @return Response
     */
    public function latest(Request $request) : Response
    {
        $creator_id = $request->user()->id;

        $listData = $this->codelabsModel->getList();
        $listDataArray = $listData->toArray();
        $latestData = reset($listDataArray['data']);

        if($latestData){
            return CatchResponse::success($latestData);
        }else{ //没有历史数据，新建一个codelabs数据返回

            $newPK = $this->codelabsModel->storeBy(['template_file'=>'elmform.stub','creator_id'=>$creator_id]);

            $listData = $this->codelabsModel->find($newPK);
            $latestData = $listData->toArray();
            return CatchResponse::success($latestData);
        }
    }

    /**
     *
     * @time 2021/11/02 09:12
     * @return Response
     */
    public function generate(Request $request) : Response
    {
        $creator_id = $request->user()->id;
        $id = input('id');
        $codelabs = $this->codelabsModel->findBy($id);
        $codelabsTemplate = CodelabsTemplates::where('filename',$codelabs->template_file)->find();
        if(!$codelabs->template_code && !$codelabsTemplate){
            return CatchResponse::fail('请先输入模板代码或选择模板文件');
        }
        if(!$codelabs->data_structure && !$codelabs->data_source){
            return CatchResponse::fail('请先输入数据结构或设置数据源表名');
        }
        if(!$codelabs->algorithm && !$codelabs->command){
            return CatchResponse::fail('请先输入算法代码或选择算法文件');
        }
        if(!$codelabs->config_data){
            return CatchResponse::fail('请先进行模板配置');
        }
        if(!$codelabs->output){
            return CatchResponse::fail('请先进行输出设置');
        }

        //SaaS版清空危险输入，以防不可预计的安全问题
        //$codelabs->output = '';

        $result = Console::call($codelabs->command, [$codelabs->data_source,'-d',$codelabs->data_structure,'-c',$codelabs->config_data,'-t',$codelabsTemplate->filename,'-e',$codelabs->template_code,'-o',$codelabs->output,'-i',$codelabs->input,'-a',false]);
        $res = $result->fetch();

        return CatchResponse::success($res);
    }

    /**
     *
     * @time 2021/11/03 12:32
     * @param Request $request
     * @return Response
     */
    public function savefile($id, Request $request) : Response
    {
        $codelabs = $this->codelabsModel->findBy($id);
        if(!$codelabs->output){
            return CatchResponse::fail('请先进行输出设置');
        }
        $outputArray = json_decode($codelabs->output,true);
        $inputArray = json_decode($codelabs->input,true);
        //controller url
        $class = $inputArray['controller'];
        $class = explode('\\', $class);
        $controllerName = lcfirst(array_pop($class));

        //vue文件的保存,默认覆盖已有文件
        if($outputArray['project_dir']){
            file_put_contents($outputArray['project_dir'].DIRECTORY_SEPARATOR . 'src' .DIRECTORY_SEPARATOR . 'views' . DIRECTORY_SEPARATOR.$outputArray['module'] . DIRECTORY_SEPARATOR .$outputArray['path']. DIRECTORY_SEPARATOR . $outputArray['filename'] .'.vue', $request->post('result'));
        }elseif($outputArray['module'] && $outputArray['path'] && $outputArray['filename']){
            file_put_contents(CatchAdmin::moduleViewDirectory($outputArray['module'],$outputArray['path']) . $outputArray['filename'] .'.vue', $request->post('result'));
        }
        //保存router.js
        $fullFilename = '';
        if($outputArray['project_dir']){
            $fullFilename = $outputArray['project_dir'].DIRECTORY_SEPARATOR . 'src' .DIRECTORY_SEPARATOR . 'views' . DIRECTORY_SEPARATOR.$outputArray['module'] . DIRECTORY_SEPARATOR. 'router.js';
        }elseif($outputArray['module'] && $outputArray['path'] && $outputArray['filename']){
            $fullFilename = CatchAdmin::moduleRouterjsDirectory($outputArray['module']) . 'router.js';
        }
        if (! FileSystem::exists($fullFilename)) {  //没有router.js,从模板新建
            //加载router.js模板
            $routerjsstub = file_get_contents(root_path(). DIRECTORY_SEPARATOR . 'extend' . DIRECTORY_SEPARATOR . 'catcher' . DIRECTORY_SEPARATOR . 'command'  . DIRECTORY_SEPARATOR . 'stubs' . DIRECTORY_SEPARATOR .'elm' . DIRECTORY_SEPARATOR . 'routerjs.stub');

            //替换routerjs.stub中的变量
            $routerjs = str_replace("vue-replace-module",$outputArray['module'],$routerjsstub);
            $routerjs = str_replace("vue-replace-path",$outputArray['path'],$routerjs);
            $routerjs = str_replace("vue-replace-filename",$outputArray['filename'],$routerjs);
            $routerjs = str_replace("vue-replace-controller",$controllerName,$routerjs);
            //保存router.js
            file_put_contents($fullFilename, $routerjs);
        }else{  //从已有router.js添加内容
            $routerjs = file_get_contents($fullFilename);
            $appendRouter = $outputArray['module'].'_'.$controllerName.": () => import('@/views/".$outputArray['module']."/".$outputArray['path']."/".$outputArray['filename']."')" ;
            $routerjs = rtrim(substr($routerjs,0,strpos($routerjs, '}'))).','.PHP_EOL .$appendRouter.PHP_EOL.'}';
            //保存router.js
            file_put_contents($fullFilename, $routerjs);
        }

        return CatchResponse::success($this->codelabsModel->updateBy($id, $request->post()));
    }

    /**
     *
     * @time 2021/11/03 12:32
     * @param Request $request
     * @return Response
     */
    public function share(Request $request)
    {
        $param = input('post.');
        $host = trim(Utils::config('appstoreserver.host'));//获取管理后台配置的应用市场服务地址 http://serv.uctoo.com
        $codelabs = $this->codelabsModel->findBy($param['id'])->toArray();
        unset($codelabs['id']);
        unset($codelabs['creator_id']);
        unset($codelabs['created_at']);
        unset($codelabs['updated_at']);
        if($param['appstore_user_token'] != 'Bearerundefined'){
                $response = Http:: withHost($host)   //指定SaaS平台
                ->withHeaders(['Authorization'=>$param['appstore_user_token']])  //采用服务端帐号认证
                ->withVerify(false)    //无需SSL验证
                ->product('')    //如果指定产品 则必填参数
                ->post('/codelabs', $codelabs);  //当前输入的应用市场帐号
                $res = json_decode($response->body(),true);
                if($res['code'] == 10000){
                    return $res;
                }else{
                    return CatchResponse::fail('分享代码至应用市场错误');
                }
        }else{
                return CatchResponse::fail('请先登录应用市场');
        }

    }
}